From ffce2a5dd4250b6c8e50f1231047eb0c4b468e7a Mon Sep 17 00:00:00 2001 From: robertlipe Date: Wed, 5 Dec 2012 19:13:26 +0000 Subject: [PATCH] Steven adds color rotate option to KML writer. --- gpsbabel/kml.c | 84 +++++++++++++++++-- .../formats/options/kml-rotate_colors.xml | 8 ++ 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 gpsbabel/xmldoc/formats/options/kml-rotate_colors.xml diff --git a/gpsbabel/kml.c b/gpsbabel/kml.c index ccd023c09..ded3f6948 100644 --- a/gpsbabel/kml.c +++ b/gpsbabel/kml.c @@ -42,6 +42,7 @@ static char* opt_trackdirection = NULL; static char* opt_units = NULL; static char* opt_labels = NULL; static char* opt_max_position_points = NULL; +static char *opt_rotate_colors = NULL; static int export_lines; static int export_points; @@ -51,6 +52,7 @@ static int extrude; static int trackdata; static int trackdirection; static int max_position_points; +static int rotate_colors; static int line_width; static int html_encrypt; @@ -162,6 +164,11 @@ arglist_t kml_args[] = { "Retain at most this number of position points (0 = unlimited)", "0", ARGTYPE_INT, ARG_NOMINMAX }, + { + "rotate_colors", &opt_rotate_colors, + "Rotate colors for tracks and routes (default automatic)", + NULL, ARGTYPE_FLOAT, "0", "360" + }, ARG_TERMINATOR }; @@ -182,8 +189,61 @@ struct { #define ICON_MULTI_TRK ICON_BASE "track-directional/track-0.png" #define ICON_DIR ICON_BASE "track-directional/track-%d.png" // format string where next arg is rotational degrees. +static struct { + float seq; + float step; + gb_color color; +} kml_color_sequencer; +#define KML_COLOR_LIMIT 204 /* allowed range [0,255] */ + #define MYNAME "kml" +static void kml_init_color_sequencer(unsigned int steps_per_rev) +{ + float color_step; + if (rotate_colors) { + color_step = atof(opt_rotate_colors); + if (color_step > 0.0f) { + // step around circle by given number of degrees for each track(route) + kml_color_sequencer.step = ((float)KML_COLOR_LIMIT) * 6.0f * color_step / 360.0f; + } else { + // one cycle around circle for all the tracks(routes) + kml_color_sequencer.step = ((float)KML_COLOR_LIMIT) * 6.0f / ((float)steps_per_rev); + } + kml_color_sequencer.color.opacity=255; + kml_color_sequencer.seq = 0.0f; + } +} + +static void kml_step_color(void) +{ + int color_seq; + // Map kml_color_sequencer.seq to an integer in the range [0, KML_COLOR_LIMIT*6). + // Note that color_seq may be outside this range if the cast from float to int fails. + color_seq = ((int) kml_color_sequencer.seq) % (KML_COLOR_LIMIT * 6); +#ifdef KML_COLOR_DEBUG + printf("kml_color_sequencer seq %f %d, step %f\n",kml_color_sequencer.seq, color_seq, kml_color_sequencer.step); +#endif + if ((color_seq >= (0*KML_COLOR_LIMIT)) && (color_seq < (1*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (0)<<16 | (color_seq)<<8 | (KML_COLOR_LIMIT); + } else if ((color_seq >= (1*KML_COLOR_LIMIT)) && (color_seq < (2*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (0)<<16 | (KML_COLOR_LIMIT)<<8 | (2*KML_COLOR_LIMIT-color_seq); + } else if ((color_seq >= (2*KML_COLOR_LIMIT)) && (color_seq < (3*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (color_seq-2*KML_COLOR_LIMIT)<<16 | (KML_COLOR_LIMIT)<<8 | (0); + } else if ((color_seq >= (3*KML_COLOR_LIMIT)) && (color_seq < (4*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (KML_COLOR_LIMIT)<<16 | (4*KML_COLOR_LIMIT-color_seq)<<8 | (0); + } else if ((color_seq >= (4*KML_COLOR_LIMIT)) && (color_seq < (5*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (KML_COLOR_LIMIT)<<16 | (0)<<8 | (color_seq-4*KML_COLOR_LIMIT); + } else if ((color_seq >= (5*KML_COLOR_LIMIT)) && (color_seq < (6*KML_COLOR_LIMIT))) { + kml_color_sequencer.color.bbggrr = (6*KML_COLOR_LIMIT-color_seq)<<16 | (0)<<8 | (KML_COLOR_LIMIT); + } else { // should not occur, but to be safe generate a legal color. + fprintf(stderr, "Error in color conversion - using default color.\n"); + kml_color_sequencer.color.bbggrr = (102)<<16 | (102)<<8 | (102); + } + // compute next color. + kml_color_sequencer.seq = kml_color_sequencer.seq + kml_color_sequencer.step; +} + #if ! HAVE_LIBEXPAT static void kml_rd_init(const char* fname) @@ -947,15 +1007,24 @@ static void kml_output_tailer(const route_head* header) } kml_write_xml(1, "\n"); kml_write_xml(0, "Path\n"); - kml_write_xml(0, "#lineStyle\n"); - if (header->line_color.bbggrr >= 0 || header->line_width >= 0) { + if (!rotate_colors) + kml_write_xml(0, "#lineStyle\n"); + if (header->line_color.bbggrr >= 0 || header->line_width >= 0 || rotate_colors) { kml_write_xml(1, "\n"); @@ -1840,6 +1909,7 @@ void kml_write(void) export_track = (0 == strcmp("1", opt_export_track)); floating = (!! strcmp("0", opt_floating)); extrude = (!! strcmp("0", opt_extrude)); + rotate_colors = (!! opt_rotate_colors); trackdata = (!! strcmp("0", opt_trackdata)); trackdirection = (!! strcmp("0", opt_trackdirection)); line_width = atol(opt_line_width); @@ -1946,6 +2016,7 @@ void kml_write(void) kml_write_xml(0, "Tracks\n"); } + kml_init_color_sequencer(track_count()); if (export_track) { track_disp_all(kml_mt_hdr, kml_mt_tlr, NULL); } @@ -1964,6 +2035,7 @@ void kml_write(void) kml_write_xml(1, "\n"); kml_write_xml(0, "Routes\n"); + kml_init_color_sequencer(route_count()); route_disp_all(kml_route_hdr, kml_route_tlr, kml_route_disp); kml_write_xml(-1, "\n"); diff --git a/gpsbabel/xmldoc/formats/options/kml-rotate_colors.xml b/gpsbabel/xmldoc/formats/options/kml-rotate_colors.xml new file mode 100644 index 000000000..4e3ef0e64 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/kml-rotate_colors.xml @@ -0,0 +1,8 @@ + +With this option GPSBabel uses different colors for each track or route. +If this option is used without a value then the colors are automatically selected such +that the spectrum will be rotated through once for all the tracks and once for all the routes. +If this option is used with a positive value then the value is interpreted as the number of degrees +in the color circle between adjacent tracks or routes. +This option takes precedence over line_color. + -- 2.30.2